package drds.common.db.sql_mapping.configuration;


import drds.common.db.sql_mapping.sql_execute.Mapper;
import drds.common.db.sql_mapping.sql_execute.MapperExecutionContext;
import drds.common.db.sql_mapping.sql_execute.MapperInterfaceProxyFactory;
import lombok.extern.slf4j.Slf4j;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

@Slf4j
public class Configuration {

    protected final Set<String> mapperXmlIdSet = new HashSet<>();
    //
    protected final Map<String, Mapper> mapperIdToMapperMap = new HashMap<>();
    private final Map<Class<?>, MapperInterfaceProxyFactory<?>> mapperInterfaceClassToMapperInterfaceProxyFactoryMap = new HashMap<>();
    protected final Map<String, ParameterMap> parameterMapIdToParameterMapMap = new HashMap<>();
    protected final Map<String, ResultMap> resultMapIdToResultMapMap = new HashMap<>();
    //


    public Configuration() {
    }

    //
    public <T> void addMapperInterfaceClass(Class<T> type) {
        mapperInterfaceClassToMapperInterfaceProxyFactoryMap.put(type, new MapperInterfaceProxyFactory<>(type));
    }

    @SuppressWarnings("unchecked")
    public <T> T getMapper(Class<T> type, MapperExecutionContext mapperExecutionContext) {
        final MapperInterfaceProxyFactory<T> mapperInterfaceProxyFactory = (MapperInterfaceProxyFactory<T>) mapperInterfaceClassToMapperInterfaceProxyFactoryMap.get(type);
        if (mapperInterfaceProxyFactory == null) {
            throw new RuntimeException("Type " + type + " is not known to the MapperRegistry.");
        }
        return mapperInterfaceProxyFactory.newInstance(mapperExecutionContext);
    }
//

    public void addMapper(Mapper mapper) {
        mapperIdToMapperMap.put(mapper.getId(), mapper);
    }

    public Mapper getMapper(String mapperId) {
        return mapperIdToMapperMap.get(mapperId);
    }

    public boolean hasMapper(String mapperId) {
        return mapperIdToMapperMap.containsKey(mapperId);
    }

    //
    public void addMapperXmlId(String mapperXmlId) {
        mapperXmlIdSet.add(mapperXmlId);
    }

    public boolean containsMapperXmlId(String mapperXmlId) {
        return mapperXmlIdSet.contains(mapperXmlId);
    }

    //
    public void addParameterMap(ParameterMap parameterMap) {
        parameterMapIdToParameterMapMap.put(parameterMap.getId(), parameterMap);
    }

    public ParameterMap getParameterMap(String parameterMapId) {
        return parameterMapIdToParameterMapMap.get(parameterMapId);
    }

    //
    public void addResultMap(String id, ResultMap resultMap) {
        if (resultMapIdToResultMapMap.containsKey(id)) {
            throw new IllegalArgumentException("resultMap(id=" + id + ")已经存在");
        }
        resultMapIdToResultMapMap.put(id, resultMap);
    }

    public ResultMap getResultMap(String resultMapId) {
        return resultMapIdToResultMapMap.get(resultMapId);
    }
    //


}
